﻿using IP2Region;
using System.Net;

namespace D.Util.UtilIp
{
    /// <summary>
    /// IP2Region
    /// </summary>
    public static class IpUtil
    {
        /// <summary>
        ///  根据Ip地址获取城市
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static string GetIpAddress(string ip)
        {
            try
            {
                using (var _search = new DbSearcher(Environment.CurrentDirectory + @"/ip2region.db"))
                {
                    return _search.MemorySearch(ip).Region;
                }
            }
            catch (Exception ex)
            {
                return Environment.CurrentDirectory + @"/ip2region.db" + ex.Message;
            }
        }

        /// <summary>
        /// 是否是禁区
        /// </summary>
        /// <param name="ip">客户端ip地址</param>
        /// <param name="city">城市</param>
        /// <returns></returns>
        public static bool IsDenyIpAddress(this string ip, string city)
        {
            var pos = GetIpAddress(ip);
            return pos.Contains(city);
        }

        /// <summary>
        /// 判断IP地址在不在某个IP地址段
        /// </summary>
        /// <param name="ip">需要判断的IP地址</param>
        /// <param name="begin">起始地址</param>
        /// <param name="ends">结束地址</param>
        /// <returns></returns>
        public static bool IpAddressInRange(this string ip, string begin = "192.168.1.1", string ends = "192.168.2.255")
        {
            uint current = IPToID(ip);
            return current >= IPToID(begin) && current <= IPToID(ends);
        }

        /// <summary>
        /// IP地址转换成数字
        /// </summary>
        /// <param name="addr">IP地址</param>
        /// <returns>数字,输入无效IP地址返回0</returns>
        private static uint IPToID(string addr)
        {
            if (!IPAddress.TryParse(addr, out var ip))
            {
                return 0;
            }

            // 便是IPAddress自带的将IP地址按“.”分割后的数组
            byte[] bInt = ip.GetAddressBytes();

            // 将一组数字进行移位计算得到结果
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(bInt);
            }
            return BitConverter.ToUInt32(bInt, 0);
        }
    }
}
